﻿namespace com.crownpack.InitiativesDao
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;

    using com.crownpack.Extensions.SharePointExtensions;
    using com.crownpack.Extensions.StringExtensions;
    using com.crownpack.Extensions.SymbolExtensions;
    using com.crownpack.SharePoint;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Linq;

    using Context = InitiativesDataContext;

    using ReferenceObject = InitiativesConfiguration;

    public class InitiativesConfigurationDao : BaseDao
    {
        #region Fields

        public const string ListName = "initiativesconfig";

        #endregion Fields

        #region Constructors

        public InitiativesConfigurationDao( )
            : base(ListName)
        {
            CurrentWebUrl = SPContext.Current.Site.RootWeb.Url;
        }

        public InitiativesConfigurationDao( string currentWebUrl )
            : base(ListName)
        {
            using ( SPSite spSite = new SPSite( currentWebUrl ) )
            {
                CurrentWebUrl = spSite.RootWeb.Url;
            }
        }

        #endregion Constructors

        #region Methods

        public ReferenceObject Add( ReferenceObject value )
        {
            ReferenceObject p = null;
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists.GetListByRootFolder( ListName );
                    SPListItem item = spList.Items.Add( );
                    item.SetValue<bool>( Item.GetColumnName<ReferenceObject>( p.GetPropertySymbol( a => a.Active ) ), value.Active.HasValue ? value.Active.Value : false );
                    item.SetValue<double?>( Item.GetColumnName<ReferenceObject>( p.GetPropertySymbol( a => a.ParentCustomerNo ) ), value.ParentCustomerNo );
                    item.SetValue<string>( Item.GetColumnName<ReferenceObject>( p.GetPropertySymbol( a => a.SourceList ) ), value.SourceList );
                    item.SetValue<string>( Item.GetColumnName<ReferenceObject>( p.GetPropertySymbol( a => a.Title ) ), value.Title );
                    item.SetValue<SPFieldUrlValue>( Item.GetColumnName<ReferenceObject>( p.GetPropertySymbol( a => a.ClientSite ) ), new SPFieldUrlValue
                    {
                        Description = value.ClientSiteDescription,
                        Url = value.ClientSiteUrl
                    } );

                    item.Update( );
                    return Get( item.UniqueId );
                }
            }
        }

        public void Delete( int id )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists.GetListByRootFolder( ListName );
                    spList.Items.DeleteItemById( id );
                }
            }
        }

        public void DeleteByClientSite( string url )
        {
            InitiativesConfiguration configuration = GetByClientSite( url );
            if ( configuration != null )
                Delete( configuration.Id.Value );
        }

        public ReferenceObject Get( int id )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<ReferenceObject> l = c.GetList<ReferenceObject>( ListTitle );
                ReferenceObject v = ( from o in l
                                      where o.Id.HasValue && o.Id.Value == id
                                      select o ).SingleOrDefault( );
                return v;
            }
        }

        public ReferenceObject Get( Guid id )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<ReferenceObject> l = c.GetList<ReferenceObject>( ListTitle );
                ReferenceObject v = ( from o in l
                                      where o.UniqueId == id
                                      select o ).SingleOrDefault( );
                return v;
            }
        }

        //public ReferenceObject GetAbsoluteByClientSite( string clientSite )
        //{
        //    using ( Context c = new Context( CurrentWebUrl ) )
        //    {
        //        EntityList<ReferenceObject> l = c.GetList<ReferenceObject>( ListTitle );
        //        List<ReferenceObject> v = ( from o in l
        //                                    where
        //                                    resolveUrl( o.ClientSiteUrl ).Equals( clientSite, StringComparison.OrdinalIgnoreCase )
        //                                    select o ).DefaultIfEmpty( ).ToList( );
        //        if ( v.Count == 1 && v[ 0 ] == null )
        //            v.Clear( );
        //        if ( v.Count >= 1 )
        //            return resolveObject( v[ 0 ] );
        //        else
        //            return null;
        //    }
        //}
        public ReferenceObject GetByClientSite( string clientSite )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<ReferenceObject> l = c.GetList<ReferenceObject>( ListTitle );
                List<ReferenceObject> v = ( from o in l
                                            where
                                            o.Active.Value &&
                                            resolveUrl( o.ClientSiteUrl ).Equals( clientSite, StringComparison.OrdinalIgnoreCase )
                                            select o ).DefaultIfEmpty( ).ToList( );
                if ( v.Count == 1 && v[ 0 ] == null )
                    v.Clear( );
                if ( v.Count >= 1 )
                    return resolveObject( v[ 0 ] );
                else
                    return null;
            }
        }

        public ReferenceObject GetByParentCustomerNo( double? parentCustomerNo )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<ReferenceObject> l = c.GetList<ReferenceObject>( ListTitle );
                List<ReferenceObject> v = ( from o in l
                                            where
                                            o.Active.Value &&
                                            o.ParentCustomerNo.HasValue && o.ParentCustomerNo.Value == parentCustomerNo.Value
                                            select o ).DefaultIfEmpty( ).ToList( );
                if ( v.Count == 1 && v[ 0 ] == null )
                    v.Clear( );
                if ( v.Count >= 1 )
                    return resolveObject( v[ 0 ] );
                else
                    return null;
            }
        }

        ReferenceObject clean( ReferenceObject value )
        {
            return new ReferenceObject
            {
                Active = value.Active,
                ClientSiteDescription = value.ClientSiteDescription,
                ClientSiteUrl = value.ClientSiteUrl,
                ClientSite = new SPFieldUrlValue
                {
                    Description = value.ClientSiteDescription,
                    Url = value.ClientSiteUrl
                }.ToString( ),
                ParentCustomerNo = value.ParentCustomerNo,
                SourceList = value.SourceList,
                Title = value.Title
            };
        }

        ReferenceObject resolveObject( ReferenceObject value )
        {
            value.ClientSiteUrl = resolveUrl( value.ClientSiteUrl );
            return value;
        }

        string resolveUrl( string url )
        {
            Uri currentWeb = new Uri( CurrentWebUrl );
            Uri uri = new Uri( url );
            UriBuilder ub = new UriBuilder( );
            ub.Host = currentWeb.Host;
            ub.Scheme = currentWeb.Scheme;
            if ( currentWeb.Port > 0 )
                ub.Port = currentWeb.Port;
            ub.Path = uri.LocalPath;
            string s = ub.ToString( );
            ub = null;
            return s;
        }

        #endregion Methods
    }
}